package com.lz.sports.vm.manager

import android.text.Editable
import android.text.TextUtils
import android.widget.Toast
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.MutableLiveData
import com.jeremyliao.liveeventbus.LiveEventBus
import com.lz.comm.SP
import com.lz.library.base.BaseModel
import com.lz.library.base.BaseViewModel
import com.lz.library.extension.APP
import com.lz.library.extension.resString
import com.lz.sports.LogUtils
import com.lz.sports.R
import com.lz.sports.bean.ExamResult
import com.lz.sports.bean.Examinee
import com.lz.sports.core.*
import com.lz.sports.db.ExamineeDatabase
import com.lz.sports.utils.ToastUtils
import com.lz.sports.utils.toArrayList
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.*

//考生管理
class ExamManagerViewModel : BaseViewModel<BaseModel>() {

    private val examPlanId = ProjectManager.examPlanId()

    //考区ID
    private val examAreaId = ProjectManager.examAreaId()

    //考点ID
    private val examSiteId = ProjectManager.examSiteId()

    //搜索关键词, 清除, 搜索状态
    val keywordStr = MutableLiveData<String>()
    var showClear = MutableLiveData(false)
    val searchEnabled = MutableLiveData(false)

    //显示完整信息
    val showAll = MutableLiveData(false)

    //添加考生
    var showAdd = MutableLiveData(false)

    //检录状态
    val checkStates by lazy { R.array.managerCheckState.toArrayList() }
    var checkPosition = 0
    val checkState = MutableLiveData<String>()

    //考试状态
    val examStates by lazy { R.array.managerExamState.toArrayList() }
    var examPosition = 0
    val examState = MutableLiveData<String>()

    //上传状态
    val uploadStates by lazy { R.array.managerUploadState.toArrayList() }
    var uploadPosition = 0
    val uploadState = MutableLiveData<String>()

    //所有学生数量
    val totalStr = MutableLiveData<String>()

    //考生列表
    val examResultList = MutableLiveData<List<ExamResult>>()

    private var listJob: Job? = null
    private var keyword: String? = null

    //操作完成刷新
    val operatorOver = MutableLiveData(false)

    override fun onCreate(owner: LifecycleOwner) {
        showAdd.value = SP.getBoolean(K_ADD_STUDENT_AUTO, v_add_student_auto) && ProjectManager.hasPlanInit()
        checkState.value = checkStates.getOrNull(checkPosition)
        examState.value = examStates.getOrNull(examPosition)
        uploadState.value = uploadStates.getOrNull(uploadPosition)
        LiveEventBus.get("ExamineeAdd_examinee", Examinee::class.java).observe(owner) {
            findExamineeList()
        }
        findExamineeList()
    }

    private fun findExamineeList() {
        listJob?.cancel()
        listJob = launch {
            flow {
                emit(ExamineeDatabase.get().examResults(
                    checkPosition,
                    examPosition,
                    uploadPosition,
                    examPlanId,
                    examAreaId,
                    examSiteId,
                    keyword
                ))
            }.flowOn(Dispatchers.IO)
                .onStart {
                    updateDialogLoading(true)
                }.onCompletion {
                    updateDialogLoading(false)
                }
                .collect {
                    examResultList.value = it
                    var maleCount = 0
                    it.forEach { result -> if (result.examinee!!.isMale()) maleCount++ }
                    totalStr.value =
                        APP.resources.getString(R.string.manager_total, it.size, maleCount, it.size - maleCount)
                }
        }
    }

    fun afterTextChanged(editable: Editable) {
        showClear.value = editable.isNotEmpty()
        searchEnabled.value = !TextUtils.isEmpty(editable)
    }

    fun search() {
        this.keyword = keywordStr.value?.trim()
        findExamineeList()
    }

    fun clearSearch() {
        if (!TextUtils.isEmpty(keyword)) {
            keyword = null
            findExamineeList()
        }
    }

    //设置成缺考
    fun lack(examResultList: List<ExamResult>) {
        if (examResultList.isEmpty()) {
            ToastUtils.showMyToast(R.string.manager_empty, Toast.LENGTH_LONG)
            return
        }
        val unFitList = ArrayList<ExamResult>()
        val fitList = ArrayList<ExamResult>()
        if (SP.getInt(K_RULE_EXAM_CONDITION, v_ruleExamCondition) == 0) {//未考试的缺考设置
            examResultList.forEach {
                if (it.hasExamined()) unFitList.add(it) else fitList.add(it.apply { setLackState() })
            }
        } else {
            val maxExamineeCount = SP.getInt(K_RULE_EXAM_COUNT, v_ruleExamCount)
            examResultList.forEach {
                if (it.examCount >= maxExamineeCount) unFitList.add(it) else fitList.add(it.apply { setLackState() })
            }
        }
        if (fitList.isNotEmpty()) {
            launch {
                ExamineeDatabase.get().lackExamResults(fitList)
            }
            operatorOver.value = true
        }
        val toast = StringBuilder()
        var index = 0
        if (unFitList.isNotEmpty()) {
            while (index < 2 && index < unFitList.size) {
                toast.append(unFitList[index].examinee!!.studentName).append(',')
                index++
            }
            toast.deleteCharAt(toast.length - 1)
            if (unFitList.size > 2) toast.append(R.string.manager_many.resString())
            toast.append(R.string.manager_lack_none.resString())
        }
        index = 0
        if (fitList.isNotEmpty()) {
            while (index < 2 && index < fitList.size) {
                toast.append(fitList[index].examinee!!.studentName).append(',')
                index++
            }
            toast.deleteCharAt(toast.length - 1)
            if (fitList.size > 2) toast.append("..等")
            toast.append(R.string.manager_lacked.resString())
        }
        LogUtils.i("toast = $toast")
        ToastUtils.showMyToast(toast.toString(), Toast.LENGTH_LONG)
        findExamineeList()
    }

    fun selectCheck(position: Int) {
        if (checkPosition == position) return
        checkPosition = position
        checkState.value = checkStates.getOrNull(checkPosition)
        findExamineeList()
    }

    fun selectExam(position: Int) {
        if (examPosition == position) return
        examPosition = position
        examState.value = examStates.getOrNull(examPosition)
        findExamineeList()
    }

    fun selectUpload(position: Int) {
        if (uploadPosition == position) return
        uploadPosition = position
        uploadState.value = uploadStates.getOrNull(uploadPosition)
        findExamineeList()
    }
}